package io.mft.commons.db;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.mft.commons.function.response.kv.KVMap;

/**
 * 异步批量更新
 * @说明：TODO
 * @类型名称：AsyncBatchUpdateDbExecutor
 * @创建者: 胡常建  
 * @创建时间: 2021年9月15日 上午10:55:46
 * @修改者: 胡常建  
 * @修改时间: 2021年9月15日 上午10:55:46
 */
public class AsyncBatchUpdateDbExecutor<T> extends BaseAsyncBatchDbExecutor<T>{

	@SuppressWarnings("unchecked")
	public static <RT> AsyncBatchUpdateDbExecutor<RT> getInstance(Class<?>  owner,String aliasId,String dataSourceId,String tbName,int batchSize,int batchWorkerNumber) {
		String id=BaseAsyncBatchDbExecutor.class.getName()+"-"+aliasId+"-"+owner.getName()+"-"+dataSourceId+"-"+tbName+"-update";
		if (map.containsKey(id)) {
			Object object= map.get(id);
			 AsyncBatchUpdateDbExecutor<RT> ab=( AsyncBatchUpdateDbExecutor<RT>)object;
			return ab;
		}
		synchronized (map) {
			if (!map.containsKey(id)) {
				try {
					AsyncBatchUpdateDbExecutor<RT> instancExecutor=new AsyncBatchUpdateDbExecutor<RT>(owner, aliasId, dataSourceId, tbName, batchSize, batchWorkerNumber);
					map.put(id, instancExecutor);
				} catch (Exception e) {
					logger.error("",e);
				}
			}
		}
		Object object= map.get(id);
		AsyncBatchUpdateDbExecutor<RT> ab=(AsyncBatchUpdateDbExecutor<RT>)object;
		return ab;
	}
	protected <AB extends BaseAsyncBatchDbExecutor<T>> AsyncBatchUpdateDbExecutor(Class<?> owner, String aliasId, String dataSourceId, String tbName,
			int batchSize, int batchWorkerNumber) {
		super(owner, aliasId, dataSourceId, tbName, batchSize, batchWorkerNumber);
	}

	private String[] where;
	public void where(String ...where) {
		this.where=where;
	}
	@Override
	protected int[] batch(String datasourceId, String tbName, List<KVMap> parameters) {
		int[] s=BatchExecuteUtil.executeUpdate(datasourceId, tbName, where, parameters);
		return s;
	}

	
	@Override
		protected List<List<KVMap>> splitGroupUniqueBatch(List<KVMap> parameters) {
		    Map<String, KVMap> kvs=new HashMap<>();
			List<KVMap> list=new ArrayList<KVMap>();
			parameters.forEach(e->{
				 String whereKey=buildWhereKey(e);
				 if (!kvs.containsKey(whereKey)) {
					 kvs.put(whereKey, e);
				 }else {
					 list.add(e);
				 }
			});
			List<KVMap> kvsList=new ArrayList<>(kvs.values());
			List<List<KVMap>> resultList=new ArrayList<>();
			resultList.add(kvsList);
			boolean isNeedSplitGroup=false;
			Map<String, KVMap> map=new HashMap<>();
			for (KVMap kvMap : list) {
				String whereKey=buildWhereKey(kvMap);
				if (!map.containsKey(whereKey)) {
					map.put(whereKey, kvMap);
				}else {
					isNeedSplitGroup=true;
					break;
				}
			}
			if (isNeedSplitGroup) {
				List<List<KVMap>> ls=splitGroupUniqueBatch(list);
				resultList.addAll(ls);
			}else {
				resultList.add(list);
			}
			return resultList;
		}
	
	
	private String buildWhereKey(KVMap kvMap) {
		 String whereKey="";
		 for (int i = 0; i < where.length; i++) {
			 String v=kvMap.getStr(where[i]);
			 whereKey=whereKey+v+":";
		 }
		 return whereKey;
	}
}
